package ycoa.data.classes

import ycoa.data.classes.Class

import com.google.appengine.api.datastore.*
import static com.google.appengine.api.datastore.FetchOptions.Builder.*

import com.google.appengine.api.datastore.Entity

public class ClassFactory {

  private static ClassFactory ref = null
  private datastore = null
  private ClassFactory() {
    initialize()
  }
  private void initialize() {
    datastore = DatastoreServiceFactory.getDatastoreService() 
  }
  public static ClassFactory getInstance() {
    if(ref==null) {
      ref = new ClassFactory()
    }
    return ref
  }

  public List getSessions() {
     def list = []
     def map = [:]
     def query = new Query("Class")
     query.addFilter("market", Query.FilterOperator.EQUAL, "AZ")
     //query.addSort("clYear", Query.SortDirection.DESCENDING)
     //query.addSort("clSemester", Query.SortDirection.DESCENDING)
     //query.addFilter("clYear", Query.FilterOperator.EQUAL, year)
     //query.addFilter("clSemester", Query.FilterOperator.EQUAL, semester)
     def preparedQuery = datastore.prepare(query)
     def entities = preparedQuery.asList(withLimit(50))
     entities.each() { e ->
       map.put("${e.clSemester} ${e.clYear}", "${e.clSemester} ${e.clYear}")
     }
     map.keySet().collect() { key -> list << key }
     return list 
  }

  public Boolean hasKey(String key) {
     def query = new Query("Class")
     query.addFilter("key", Query.FilterOperator.EQUAL, key)
     def preparedQuery = datastore.prepare(query)
     def entities = preparedQuery.asList(withLimit(1))
     def counter = 0
     entities.each() { 
       counter++
     }
     if(counter>0) { 
       return new Boolean(true)
     } else {
       return new Boolean(false)
     }
  }

  public List queryByKey(String key) {
     def query = new Query("Class")
     query.addFilter("key", Query.FilterOperator.EQUAL, key)
     def preparedQuery = datastore.prepare(query)
     def entities = preparedQuery.asList(withLimit(1))
     return entities
  }
  
  public List queryUniqueSemester(Integer year, Integer limit=1000) {
     def query = new Query("Class")
     query.addSort("clYear", Query.SortDirection.DESCENDING)
     query.addSort("clSemester", Query.SortDirection.DESCENDING)
     query.addFilter("clYear", Query.FilterOperator.EQUAL, year)
     def preparedQuery = datastore.prepare(query)
     def entities = preparedQuery.asList(withLimit(limit))
     def distinct = []
     def map = [:]
     entities.each() { e ->
       def cls = e as Class
       if(!map.containsValue(cls.clSemester)) {
         map[cls.clSemester] = cls.clSemester
         distinct << cls
       }
     }
     return distinct
  }

  public List queryUniqueYear(Integer limit=1000) {
     def query = new Query("Class")
     query.addSort("clYear", Query.SortDirection.DESCENDING)
     def preparedQuery = datastore.prepare(query)
     def entities = preparedQuery.asList(withLimit(limit))
     def distinct = []
     def map = [:]
     entities.each() { e ->
       def cls = e as Class
       if(!map.containsValue(cls.clYear)) {
         map[cls.clYear] = cls.clYear
         distinct << cls
       }
     }
     return distinct
  }

  public List queryBySession(Integer year=null, String semester=null, Integer limit=1000) {
     def query = new Query("Class")
     query.addSort("clYear", Query.SortDirection.DESCENDING)
     query.addSort("clSemester", Query.SortDirection.DESCENDING)
     if(year!=null) query.addFilter("clYear", Query.FilterOperator.EQUAL, year)
     if(semester!=null) query.addFilter("clSemester", Query.FilterOperator.EQUAL, semester)
     def preparedQuery = datastore.prepare(query)
     def entities = preparedQuery.asList(withLimit(limit))
     return entities
  }

  public List parseXml(String data, Integer start=null, Integer stop=null) {
    def list = []
    def slurper = new XmlSlurper()
    def parser = slurper.parseText(data)
    def index = 0
    if(start==null) start = -1
    if(stop==null)  stop  = 999999
    parser.'**'.findAll{it.name()=="CLASS"}.each() { node ->
      if(index>=start && index<=stop) {
        def cls = new Class()
        cls.parseXml(node)
        list << cls
      }
      index++
    }
    return list
  }

  public void loadFromResource(path, Integer start=null, Integer stop=null) {
    def data = Class.getResource(path).text
    def slurper = new XmlSlurper()
    def parser = slurper.parseText(data)
    def index = 0
    if(start==null) start = -1
    if(stop==null)  stop  = 999999
    parser.'**'.findAll{it.name()=="CLASS"}.each() { node ->
      if(index>=start && index<=stop) {
        def cls = new Class()
        cls.parseXml(node)
	def entity = cls as Entity
	entity.save()
      }
      index++
    }
  }

  public void loadFromString(data, Integer start=null, Integer stop=null) {
    def slurper = new XmlSlurper()
    def parser = slurper.parseText(data)
    def index = 0
    if(start==null) start = -1
    if(stop==null)  stop  = 999999
    parser.'**'.findAll{it.name()=="CLASS"}.each() { node ->
      if(index>=start && index<=stop) {
        def cls = new Class()
        cls.parseXml(node)
	def entity = cls as Entity
        if(!hasKey(cls.key)) {
	  entity.save()
        }
      }
      index++
    }
  }

  public void loadFromUrl(url, Integer start=null, Integer stop=null) {
    def slurper = new XmlSlurper()
    def parser = slurper.parse(url)
    def index = 0
    if(start==null) start = -1
    if(stop==null)  stop  = 999999
    parser.'**'.findAll{it.name()=="CLASS"}.each() { node ->
      if(index>=start && index<=stop) {
        def cls = new Class()
        cls.parseXml(node)
	def entity = cls as Entity
	entity.save()
      }
      index++
    }
  }

}


